<!--
* @author luguoxiang
* @date 2021-09-07
* 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <slot name="custom" :files="files" :choose="choose" :upload="upload" :remove="remove">
    <!--  img 样式  -->
    <div v-if="type === 'img'" :key="key" class="lg-upload lg-upload-img" v-bind="$attrs">
      <slot name="files" :files="files">
        <div
          v-for="(x, i) in files"
          :key="x.id"
          class="lg-upload-item"
          :class="`lg-upload-${x.status || 0}`"
          :title="x.error"
        >
          <img
            class="lg-upload-file"
            :src="getFileAccessAuthUrl(x.url, thumbLevel || 's')"
            onload="this.style.display = ''"
            onerror="this.style.display == 'none'"
            @click="clickFile(x, i)"
          />
          <div v-if="!disabled" class="lg-upload-remove" @click="remove(i)">
            <close-icon />
          </div>
        </div>
      </slot>
      <div v-if="showTrigger" class="lg-upload-item">
        <div class="lg-upload-trigger" @click="choose">
          <slot>
            <div style="text-align: center">
              <span style="font-size: 32px; font-weight: 100">+</span>
              <div style="color: var(--app-color-placeholder)">选择图片</div>
            </div>
          </slot>
        </div>
      </div>
    </div>
    <!--  table 样式  -->
    <div v-else-if="type === 'table'" :key="key" class="lg-upload lg-upload-table" v-bind="$attrs">
      <div v-if="showTrigger" class="lg-upload-trigger">
        <span @click="choose">
          <slot>
            <t-button theme="primary">选择文件</t-button>
          </slot>
        </span>
        <span v-if="manual" @click="upload">
          <slot name="upload">
            <t-button theme="success">点击上传</t-button>
          </slot>
        </span>
      </div>
      <slot name="files" :files="files">
        <table class="lg-upload-files">
          <thead>
            <tr>
              <th>文件名</th>
              <th style="width: 120px">文件大小</th>
              <th style="width: 120px">状态</th>
              <th v-if="!disabled" style="width: 80px; text-align: center">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="(x, i) in files"
              :key="x.id"
              class="lg-upload-item"
              :class="`lg-upload-${x.status || 0}`"
              :title="x.error"
            >
              <td class="t-upload__file-name">
                <span class="lg-upload-file" @click="clickFile(x, i)">
                  {{ x.name }}
                </span>
              </td>
              <td>{{ fileSize(x.size) }}</td>
              <td>
                <div class="t-upload__flow-status">
                  <template v-if="x.status === 1">
                    <time-icon />
                    <span class="lg-ellipsis">等待上传</span>
                  </template>
                  <template v-else-if="x.status === 2">
                    <loading-icon />
                    <span class="lg-ellipsis">{{ x.percent }}%</span>
                  </template>
                  <t-tooltip v-else-if="x.status === 3" :content="x.error">
                    <error-circle-icon />
                    <span class="lg-ellipsis-1 t-upload__file-flow-fail">上传失败</span>
                  </t-tooltip>
                  <template v-else>
                    <check-circle-icon />
                    <span class="lg-ellipsis-1">上传成功</span>
                  </template>
                </div>
              </td>
              <td v-if="!disabled">
                <button
                  class="t-button t-button--variant-text t-button--theme-primary t-upload__delete"
                  type="button"
                  @click="remove(i)"
                >
                  <span class="t-button__text">删除</span>
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </slot>
    </div>
    <!--  list 样式  -->
    <div v-else :key="key" class="lg-upload lg-upload-list" v-bind="$attrs">
      <div v-if="showTrigger" class="lg-upload-trigger">
        <span @click="choose">
          <slot>
            <t-button theme="primary">选择文件</t-button>
          </slot>
        </span>
        <span v-if="manual" @click="upload">
          <slot name="upload">
            <t-button theme="success">点击上传</t-button>
          </slot>
        </span>
      </div>
      <slot name="files" :files="files">
        <div class="lg-upload-files">
          <div v-for="(x, i) in files" :key="x.id" class="lg-upload-item" :class="`lg-upload-${x.status || 0}`">
            <div class="lg-upload-file" @click="clickFile(x, i)">
              {{ x.name }}
            </div>
            <div class="lg-upload-ext">
              <template v-if="x.status === 2">
                <loading-icon />
                <span class="lg-upload-percent">{{ x.percent }}%</span>
              </template>
              <template v-else>
                <time-icon v-if="x.status === 1" />
                <t-tooltip v-else-if="x.status === 3" :content="x.error">
                  <error-circle-icon />
                </t-tooltip>
                <close-icon v-if="!disabled" class="lg-upload-remove" @click="removeFile(i)" />
              </template>
            </div>
          </div>
        </div>
      </slot>
    </div>
  </slot>
  <lg-file-viewer ref="viewerRef" />
</template>

<script lang="ts" setup>
import './index.less';
import { computed, ref, watch } from 'vue';
import { CheckCircleIcon, CloseIcon, ErrorCircleIcon, LoadingIcon, TimeIcon } from 'tdesign-icons-vue-next';
import { fileSize, getFileAccessAuthUrl, nextId, ThumbnailSizeEnum } from '@/soar';
import { LgUploadProps } from '../types';
import LgFileViewer from '../LgFileViewer/index.vue';
import { LgFile, useUploader, UseUploaderOptions } from '@/soar/hooks/upload';

interface Props extends UseUploaderOptions {
  modelValue?: any;
  /**
   * 显示类型
   */
  type?: LgUploadProps['type'];
  /**
   * 是否禁用
   */
  disabled?: boolean;
  /**
   * 是否固定上传按钮不受文件数量控制
   */
  fixedTrigger?: boolean;
  /**
   * 值类型
   */
  valueType?: LgUploadProps['valueType'];
  /**
   * 文件类型控制
   */
  accept?: string;
  /**
   * 文件数量限制（值类型是url、info模式时无效）
   */
  count?: number | string;
  /**
   * 文件大小限制
   */
  size?: number | string;
  /**
   * 是否手动上传
   */
  manual?: boolean;
  /**
   * 启用匿名路径
   */
  anonUrlAble?: boolean;
  /**
   * 缩略图压缩级别
   */
  thumbLevel?: ThumbnailSizeEnum;
}

const props = defineProps<Props>();
const emits = defineEmits(['update:modelValue', 'change']);

const key = nextId();
const viewerRef = ref();

/**
 * 点击文件
 * @param file
 * @param index
 */
function clickFile(file: LgFile, index: number) {
  viewerRef.value.open({ files: files.value, index });
}

const showTrigger = computed(() => {
  if (props.disabled) {
    return false;
  }
  if (props.fixedTrigger) {
    return true;
  }
  const count = props.valueType === 'url' || props.valueType === 'info' ? 1 : props.count || Infinity;
  return files.value.length < count;
});

const { files, upload, choose, remove, updateValue } = useUploader(props, (value: any) => {
  emits('update:modelValue', value);
  emits('change', value);
});

watch(() => props.modelValue, updateValue, { immediate: true, deep: true });

function removeFile(e: any) {
  if (props.disabled) {
    return;
  }
  remove(e);
}

defineExpose({
  upload,
  choose,
  remove,
});
</script>
<script lang="ts">
export default {
  name: 'LgUpload',
};
</script>
